using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.Xml.Linq;
using Common.Interface;
using EntityFrameworkExtension.Interface;


namespace MainProcessor.MessageProcessor
{
    public class BaseProcessor<T, TU> where T : IBaseContextProcessor
        where TU : IValidateInput
    {
        private readonly string database;
        private readonly string server;
        private readonly IEnumerable<TU> validators;
        private readonly IEnumerable<T> extractions;
        private readonly IEfContext iefContext;

        public BaseProcessor(IEfContext iefcContext, IEnumerable<TU> validators, IEnumerable<T> extractions)
        {
            this.validators = validators;
            this.extractions = extractions;
            this.iefContext = iefcContext;
            database = ConfigurationManager.AppSettings["DatabaseName"];
            server = ConfigurationManager.AppSettings["ServerName"];

        }

        public bool Process(string message)
        {
            MessageProcess(message);
            Persist();
            return true;
        }

        public bool MessageProcess(string message)
        {
            XElement xElement = XElement.Parse(message);

            var errors = String.Empty;
            validators.ToList().ForEach(x =>
                                             {
                                                 var results = x.Validate(xElement);
                                                 if (results.Length != 0)
                                                     errors += results;
                                             });
            if (errors.Length > 0)
            {
                // hanndle errors
            }


            extractions.ToList().ForEach(x => x.ExtractXml(xElement));
            return true;
        }

        public void Persist()
        {
            try
            {
                //Atomic 
                using (iefContext.Open(server, database))
                {
                    foreach (IContextProcessor extraction in extractions)
                    {
                        extraction.EfContext = iefContext;
                        extraction.PopulateEf(iefContext);
                    }
                    iefContext.SaveChanges();
                }
            }
            catch (Exception ex)
            {
               //handle error;
            }
        }


       

       
    }
}
